//@author A0097091Y

package crossoff.logic;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.awt.FontFormatException;
import java.io.IOException;

import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Test;

import crossoff.db.Storage;
import crossoff.model.GUIobject;
import crossoff.model.Task;
import crossoff.ui.CrossOffGUI;

public class CommandLogicTest {

	@Before
	public void initiateGUI() throws FontFormatException, IOException {
		CrossOffGUI gui = new CrossOffGUI();
	}

	@Test
	public void testAddDeleteFloating() throws IOException, Exception {
		Storage st = Storage.getInstance();
		st.taskCache.clear();
		Task mytask;
		st.taskCache.clear();

		CommandLogic.runCommand("dinner with Tom", true);
		mytask = Storage.getInstance().taskCache.get(0);

		// check task details
		assertTrue(mytask.getDescription().equals("dinner with Tom"));
		assertEquals("check start date", null, mytask.getStart());
		assertEquals("check end date", null, mytask.getEnd());

		// edit task
		CommandLogic.runCommand("edit 1 8 apr 2014 7pm", true);
		assertTrue(mytask.getStart().equals(new DateTime(2014, 4, 8, 19, 0)));

		// delete task
		CommandLogic.runCommand("delete 1", true);
		assertTrue(Storage.getInstance().taskCache.isEmpty());

	}

	@Test
	public void testAddDeleteFromTimedEnd() throws IOException, Exception {
		Storage st = Storage.getInstance();
		Task mytask;
		st.taskCache.clear();

		CommandLogic.runCommand(
				"meeting with Kang-An from 10am to 2pm 8-4-2014", true);
		mytask = st.taskCache.get(0);

		// check task details
		assertEquals("check description", "meeting with Kang-An",
				mytask.getDescription());
		assertEquals("check start date", new DateTime(2014, 4, 8, 10, 0),
				mytask.getStart());
		assertEquals("check end date", new DateTime(2014, 4, 8, 14, 0),
				mytask.getEnd());

		// delete task
		CommandLogic.runCommand("delete 1", true);
		assertTrue(Storage.getInstance().taskCache.isEmpty());
	}

	@Test
	public void testAddDeleteFromTimedMiddle() throws IOException, Exception {
		Storage st = Storage.getInstance();
		Task mytask;
		st.taskCache.clear();
		CommandLogic.runCommand(
				"meeting from 10am to 2pm 8-4-2014 with Kang-An", true);
		mytask = st.taskCache.get(0);

		// check task details
		assertEquals("check description", "meeting with Kang-An",
				mytask.getDescription());
		assertEquals("check start date", new DateTime(2014, 4, 8, 10, 0),
				mytask.getStart());
		assertEquals("check end date", new DateTime(2014, 4, 8, 14, 0),
				mytask.getEnd());

		// delete task
		CommandLogic.runCommand("delete 1", true);
		assertTrue(Storage.getInstance().taskCache.isEmpty());
	}

	@Test
	public void testAddDeleteFromTimedBeginning() throws IOException, Exception {
		Storage st = Storage.getInstance();
		Task mytask;
		st.taskCache.clear();

		CommandLogic.runCommand(
				"from 10am to 2pm 8-4-2014 meeting with Kang-An", true);
		mytask = st.taskCache.get(0);

		// check task details
		assertEquals("check description", "meeting with Kang-An",
				mytask.getDescription());
		assertEquals("check start date", new DateTime(2014, 4, 8, 10, 0),
				mytask.getStart());
		assertEquals("check end date", new DateTime(2014, 4, 8, 14, 0),
				mytask.getEnd());

		// delete task
		CommandLogic.runCommand("delete 1", true);
		assertTrue(Storage.getInstance().taskCache.isEmpty());
	}

	@Test
	public void testEditStartDate() throws IOException, FontFormatException {
		Storage st = Storage.getInstance();
		Task mytask;
		st.taskCache.clear();

		CommandLogic.runCommand("do something", true);
		mytask = st.taskCache.get(0);

		// check task details
		assertEquals("check description", "do something",
				mytask.getDescription());
		assertEquals("check start date", null, mytask.getStart());
		assertEquals("check end date", null, mytask.getEnd());

		// edit start date
		CommandLogic.runCommand("edit 1 start 8 april 2014 7pm", true);
		assertEquals("check start date after edit", new DateTime(2014, 4, 8,
				19, 0), mytask.getStart());

		CommandLogic.runCommand("edit 1 start 8pm", true);
		assertEquals("check start date after edit", new DateTime(2014, 4, 8,
				20, 0), mytask.getStart());

		CommandLogic.runCommand("edit 1 start 9 april 2014", true);
		assertEquals("check start date after edit", new DateTime(2014, 4, 9,
				20, 0), mytask.getStart());

	}

	@Test
	public void testEditEndDate() throws IOException, FontFormatException {
		Storage st = Storage.getInstance();
		Task mytask;
		st.taskCache.clear();

		CommandLogic.runCommand("do something", true);
		mytask = st.taskCache.get(0);

		// check task details
		assertEquals("check description", "do something",
				mytask.getDescription());
		assertEquals("check start date", null, mytask.getStart());
		assertEquals("check end date", null, mytask.getEnd());

		// edit start date
		CommandLogic.runCommand("edit 1 end 8 april 2014 7pm", true);
		assertEquals("check start date after edit", new DateTime(2014, 4, 8,
				19, 0), mytask.getEnd());

		CommandLogic.runCommand("edit 1 end at 8pm", true);
		assertEquals("check start date after edit", new DateTime(2014, 4, 8,
				20, 0), mytask.getEnd());

		CommandLogic.runCommand("edit 1 end by 9 april 2014", true);
		assertEquals("check start date after edit", new DateTime(2014, 4, 9,
				20, 0), mytask.getEnd());

	}

	@Test
	public void testSearch() throws IOException, FontFormatException {
		Storage st = Storage.getInstance();
		Task foundTask;
		GUIobject toSearch;
		st.taskCache.clear();

		// search for task that exists
		CommandLogic.runCommand("do something", true);
		toSearch = CommandLogic.runCommand("search something", true);
		foundTask = toSearch.getDisplayCache().get(0);
		assertEquals("check if task is found", "do something",
				foundTask.getDescription());

		// search for task that doesn't exist
		toSearch = CommandLogic.runCommand("search foo bar", true);
		assertEquals("check that task is not found", true, toSearch
				.getDisplayCache().isEmpty());

	}

	// @author A0100704B
	@Test
	// test search for string
	public void searchString() throws IOException, FontFormatException {
		Storage st = Storage.getInstance();
		st.taskCache.clear();

		CommandAddTask.addTask("finish something by 10 mar", true);
		CommandAddTask.addTask("finish another by 11 mar", true);
		GUIobject search = CommandSearchTask.searchTask("search something");
		Task toSearch = search.getDisplayCache().get(0);
		assertTrue(toSearch.getDescription().equals("finish something"));
	}

	@Test
	// test search for numbers
	public void searchInt() throws IOException {
		Storage st = Storage.getInstance();
		st.taskCache.clear();

		CommandAddTask.addTask("finish something by 12 march", true);
		CommandAddTask.addTask("finish another task by 10 mar", true);
		GUIobject search = CommandSearchTask.searchTask("search 12");
		Task toSearch = search.getDisplayCache().get(0);
		assertTrue(toSearch.getDescription().equals("finish something"));
	}

	@Test
	// Boundary test search for task that doesn't exist
	public void searchEmptyTask() throws IOException {
		Storage st = Storage.getInstance();
		st.taskCache.clear();

		CommandAddTask.addTask("finish something by 12 march", true);
		GUIobject search = CommandSearchTask.searchTask("search nothing");
		assertTrue(search.getDisplayCache().isEmpty());
	}

}